home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / c_news / 04 / ff / ff.c < prev    next >
Text File  |  1987-07-14  |  10KB  |  342 lines

  1. /* FF.C                                                               */
  2. /*                                                                    */
  3. /* See FF.DOC for syntax and options.                                 */
  4. /*                                                                    */
  5. /* Language: Microsoft C, version 4.0 (small memory model)            */
  6. /*                                                                    */
  7. /* External files needed: DOSTYPE.H                                   */
  8. /*                                                                    */
  9. /* External functions                                                 */
  10. /*    From FINDENTR.C - findentr(), findnext()                        */
  11. /*         DTA.C      - get_DTA(). set_DTA()                          */
  12. /*                                                                    */
  13. /* Linking: LINK ff+findentr+dta                                      */
  14. /*          FINDENTR.OBJ and DTA.OBJ must be present.                 */
  15. /*                                                                    */
  16. /* Written by: Bill Mayne                                             */
  17. /*             9707 Lawndale Dr.                                      */
  18. /*             Silver Spring, MD  20901                               */
  19. /*                                                                    */
  20. /* Date written: May 19, 1987                                         */
  21. /* Revised: June 30, 1987 to support selection by file size and date. */
  22. /*          July 15, 1987 (1) default .ext of ".*" added.             */
  23. /*              (2) Command summary displayed if no arguments given.  */
  24. /*                                                                    */
  25. #include <stdio.h>
  26. #include <memory.h>
  27. #include <dos.h>
  28. #include <string.h>
  29. #include <conio.h>
  30. #include <ctype.h>
  31. #include "dostype.h"
  32.  
  33. extern void get_DTA(unsigned *,unsigned *),
  34.             set_DTA(unsigned, unsigned);
  35. extern int findentr(struct DTA_STRUCT *, char *, int),
  36.            findnext(struct DTA_STRUCT *);
  37.  
  38. int s_attr=0; /* permitted attributes (use for H,S,D) */
  39. int m_attr=0; /* excluded attributes (use for A,R)    */
  40. int r_attr=0; /* required attributes (any)            */
  41. int r_levels=9999; /* levels to search (use to restrict) */
  42. unsigned long maxsize=~(0L);
  43. unsigned long minsize=0;
  44. int cur_level=1;
  45.  
  46. /* command summary to display when no arguments */
  47. char *cmd_summary[]=
  48. {
  49. "FF.EXE - File Find utility\n",
  50. "Syntax: FF [/options] [drive:][path\\]filename[.ext]",
  51. "    or: FF [drive:][path\\]filename[.ext] [/options]\n",
  52. "Wildcards allowed in filename.ext.",
  53. "Search starts at specified (or default root) directory.",
  54. "Interrupt with CTRL-C at any time.\n",
  55. "Options:",
  56. "/I - Include attributes. Use to specify D, H, or S.",
  57. "/X - Exclude attributes. Use for A and R.",
  58. "/R - Required attributes - any of A, D, R, H, or S.",
  59. "/Yfrom:to - date/time range to select files.",
  60. "    \"from\" and \"to\" are in the form \"YYMMDDhhmm\".",
  61. "/Smin:max - size range of file to select",
  62. "/n - where n is a decimal integer (without sign) limits the depth of the search.",
  63. "/D - directory format display.\n",
  64. "See FF.DOC for details."
  65. };
  66.  
  67. /* date and time range of files to select */
  68. union
  69.   {
  70.   struct FCB_DATE field;
  71.   unsigned long date_time;
  72.   } start, enddt;
  73.  
  74. #include <main.h>
  75. {
  76. char st_dir[128];
  77. char hold_name[128], *namepart;
  78. char *p;
  79. unsigned yy,mm,dd,hh,min;
  80. int i, i_incr, j, disp_dirs=0, disp_cmds=0;
  81.  
  82. /* If no arguments display command summary */
  83. if (argc<2)
  84.   {
  85.   j=sizeof(cmd_summary)/sizeof(cmd_summary[0]);
  86.   for (i=0; i<j; puts(cmd_summary[i++]));
  87.   exit(0);
  88.   }
  89.  
  90. /* initialize date/time range to all possible values */
  91. start.date_time=0;
  92. enddt.date_time=~(0L);
  93. if (*argv[i=argc-1]=='/') i_incr=-1;
  94. else {i=1; i_incr=1;}
  95. while (i<argc && i>0 && *argv[i]=='/')
  96.   {
  97.   strupr(argv[i]);
  98.   switch (argv[i][1])
  99.     {
  100.     case 'Y':
  101.       {
  102.       yy=mm=dd=hh=min=0;
  103.       sscanf(argv[i]+2,
  104.         "%2d%2d%2d%2d%2d:",
  105.         &yy,&mm,&dd,&hh,&min);
  106.       yy-=80;
  107.       start.field.date.year=yy;
  108.       start.field.date.month=mm;
  109.       start.field.date.day=dd;
  110.       start.field.time.hours=hh;
  111.       start.field.time.minutes=min;
  112.       if (p=strchr(argv[i]+2,','))
  113.         {
  114.         yy=mm=dd=hh=mm=~0;
  115.         sscanf(p+1,
  116.         "%2d%2d%2d%2d%2d/",
  117.         &yy,&mm,&dd,&hh,&min);
  118.         yy-=80;
  119.         enddt.field.date.year=yy;
  120.         enddt.field.date.month=mm;
  121.         enddt.field.date.day=dd;
  122.         enddt.field.time.hours=hh;
  123.         enddt.field.time.minutes=min;
  124.         }
  125.       }
  126.       break;
  127.     case 'D':
  128.       disp_dirs=1;
  129.       break;
  130.     case 'I':
  131.       for (j=2; argv[i][j] && argv[i][j]!='/'; ++j)
  132.         {
  133.         switch (argv[i][j])
  134.           {
  135.           case 'A': s_attr|=ARCHIVE; break;
  136.           case 'H': s_attr|=HIDDEN; break;
  137.           case 'S': s_attr|=SYSTEM; break;
  138.           case 'D': s_attr|=DIRECTORY; break;
  139.           case 'R': s_attr|=READONLY; break;
  140.           default: printf("Invalid attribute '%c' ignored.\n",argv[i][j]);
  141.           }
  142.         }
  143.       break;
  144.     case 'R':
  145.       for (j=2; argv[i][j] && argv[i][j]!='/'; ++j)
  146.         {
  147.         switch (argv[i][j])
  148.           {
  149.           case 'A': r_attr|=ARCHIVE; break;
  150.           case 'H': r_attr|=HIDDEN; break;
  151.           case 'S': r_attr|=SYSTEM; break;
  152.           case 'D': r_attr|=DIRECTORY; break;
  153.           case 'R': r_attr|=READONLY; break;
  154.           default: printf("Invalid attribute '%c' ignored.\n",argv[i][j]);
  155.           }
  156.         }
  157.       break;
  158.     case 'X':
  159.       for (j=2; argv[i][j] && argv[i][j]!='/'; ++j)
  160.         {
  161.         switch (argv[i][j])
  162.           {
  163.           case 'A': m_attr|=ARCHIVE; break;
  164.           case 'H': m_attr|=HIDDEN; break;
  165.           case 'S': m_attr|=SYSTEM; break;
  166.           case 'D': m_attr|=DIRECTORY; break;
  167.           case 'R': m_attr|=READONLY; break;
  168.           default: printf("Invalid attribute '%c' ignored.\n",argv[i][j]);
  169.           }
  170.         }
  171.       break;
  172.     case 'S':
  173.       minsize=atol(argv[i]+2);
  174.       {
  175.       char *p=strchr(argv[i]+2,':');
  176.       if (p++)
  177.         if (isdigit(*p)) maxsize=atol(p);
  178.         else
  179.           fputs("WARNING: Max file size missing or invalid\n",stderr);
  180.       else;
  181.       }
  182.       break;
  183.     default:
  184.       if (isdigit(argv[i][1]) && argv[i][1]>'0')
  185.         r_levels=atoi(argv[i]+1);
  186.       else
  187.         fprintf(stderr,"Invalid option %s ignored\n",argv[i]);
  188.     }
  189.   if ((argv[i]=strchr(argv[i]+1,'/'))==NULL) i+=i_incr;
  190.   }
  191. if (i==0 || i==argc)
  192.   {
  193.   i=0;
  194.   argv[0]=".\\*.*";
  195.   }
  196. strupr(argv[i]);
  197. j=strlen(argv[i])-1;
  198. while (j>=0 && argv[i][j]!='\\' && argv[i][j]!=':') --j;
  199. if (j>=0)
  200.   {
  201.   if (argv[i][j]==':')
  202.     {
  203.     st_dir[j+1]='\\';
  204.     st_dir[j+2]='\0';
  205.     }
  206.   else
  207.     st_dir[j+1]='\0';
  208.   namepart=argv[i]+j+1;
  209.   while (j>=0)
  210.     {
  211.     st_dir[j]=argv[i][j];
  212.     --j;
  213.     }
  214.   }
  215. else
  216.   {
  217.   st_dir[0]='\\';
  218.   st_dir[1]='\0';
  219.   namepart=argv[i];
  220.   }
  221. strcpy(hold_name,namepart);
  222. if (strchr(hold_name,'.')==NULL) strcat(hold_name,".*");
  223. s_attr|=r_attr;
  224. trav(st_dir,hold_name,disp_dirs);
  225. }
  226.  
  227. trav(st_dir,matchname,display_dirs)
  228. char st_dir[];
  229. char matchname[];
  230. int display_dirs;
  231. {
  232. char start_directory[128];
  233. char matchname_buf[128];
  234. struct DTA_STRUCT DTA, far *FP_DTA=&DTA;
  235. unsigned save_DTA_SEG, save_DTA_OFF;
  236. int i;
  237.  
  238. kbhit(); /* allow CTRL-C interrupt even if break is off */
  239. strcpy(start_directory,st_dir);
  240. strcpy(matchname_buf,start_directory);
  241. strcat (matchname_buf,matchname);
  242.  
  243. get_DTA(&save_DTA_SEG,&save_DTA_OFF);
  244. set_DTA(FP_SEG(FP_DTA),FP_OFF(FP_DTA));
  245. if (findentr(NULL,matchname_buf,s_attr)==0)
  246.   {
  247.   int first=1;
  248.   int more=0; /* in this case 0 means something was found */
  249.   while (more==0)
  250.     {
  251.     if ((DTA.timestamp.date_time>=start.date_time) &&
  252.         (DTA.timestamp.date_time<=enddt.date_time) &&
  253.         (DTA.attr & m_attr)==0 &&
  254.         (DTA.attr & r_attr)==r_attr &&
  255.         (DTA.size <= maxsize) &&
  256.         (DTA.size >= minsize))
  257.       {
  258.       if (display_dirs)
  259.         {
  260.         if (first) {first=0; printf("%s\n",start_directory);}
  261.         display_entry(&DTA,0);
  262.         }
  263.       else display_entry(&DTA,1,start_directory);
  264.       }
  265.     more=findnext(NULL);
  266.     }
  267.   }
  268. set_DTA(save_DTA_SEG,save_DTA_OFF);
  269.  
  270. if (cur_level<r_levels)
  271.   {
  272.   ++cur_level;
  273.   /* go looking for more directories */
  274.   strcpy(matchname_buf,start_directory);
  275.   strcat(matchname_buf,"*");
  276.   if (findentr(&DTA,matchname_buf,DIRECTORY)==0)
  277.     do
  278.       if ((DIRECTORY & DTA.attr) && *DTA.name!='.')
  279.         {
  280.         /* recursively traverse subdirectory */
  281.         strcpy(matchname_buf,start_directory);
  282.         strcat(matchname_buf,DTA.name);
  283.         strcat(matchname_buf,"\\");
  284.         trav(matchname_buf,matchname,display_dirs);
  285.         }
  286.     while (findnext(&DTA)==0);
  287.   --cur_level;
  288.   }
  289. }
  290.  
  291. display_entry(DTA,disp_directory,directory)
  292. struct DTA_STRUCT *DTA;
  293. int disp_directory;
  294. char directory[];
  295. {
  296. int dir_len, name_len, size_col, yy, mm, dd, hh, min;
  297. char ampm;
  298. if (disp_directory)
  299.   {
  300.   printf("%s%n",directory,&dir_len);
  301.   size_col=32;
  302.   }
  303. else
  304.   {
  305.   putchar(' ');
  306.   dir_len=0;
  307.   size_col=12;
  308.   }
  309. printf("%s%n",(*DTA).name,&name_len);
  310. name_len+=dir_len;
  311. name_len=size_col-name_len;
  312. while (name_len>0) putchar(' '), --name_len;
  313. printf("%7lu",(*DTA).size);
  314. yy=(*DTA).timestamp.field.date.year;
  315. yy+=80;
  316. yy%=100;
  317. dd=(*DTA).timestamp.field.date.day;
  318. mm=(*DTA).timestamp.field.date.month;
  319. hh=(*DTA).timestamp.field.time.hours;
  320. min=(*DTA).timestamp.field.time.minutes;
  321. if (hh<1)
  322.   {
  323.   hh=12;
  324.   ampm='a';
  325.   }
  326. else if (hh>=12)
  327.   {
  328.   ampm='p';
  329.   if (hh>12) hh-=12;
  330.   }
  331. else
  332.   ampm='a';
  333. printf(" %2d-%0.2d-%0.2d %2d:%0.2d%c",mm,dd,yy,hh,min,ampm);
  334. putchar(' ');
  335. if ((*DTA).attr & ARCHIVE) putchar('A');
  336. if ((*DTA).attr & DIRECTORY) putchar('D');
  337. if ((*DTA).attr & SYSTEM) putchar('S');
  338. if ((*DTA).attr & HIDDEN) putchar('H');
  339. if ((*DTA).attr & READONLY) putchar('R');
  340. putchar('\n');
  341. }
  342.